﻿@using FormBuilder.Helpers
@using System.Text.Json.Nodes
@using FormBuilder.Rules
@using System.Collections.ObjectModel
@using System.ComponentModel
@using System.Collections.Specialized
@using global::FormBuilder.Models
@inject IRenderFormElementsHelper renderFormsElementsHelper
@inject IHtmlClassResolver htmlClassResolver
@implements IDisposable

<div class="@ContainerClass">
    <div class="@ContentClass">
        <div class="@FormContainerClass">
            <div class="@FormContentClass">
                @{
                    if (Context.Definition.Workflow != null && Context.Definition.Records != null)
                    {
                        var formsActingAsStep = Context.Definition.Records.Where(s => s.ActAsStep);
                        var authSteps = new List<WorkflowStep>();
                        authSteps.AddRange(Context.Definition.Workflow.GetAllParentMainLinks(Context.Execution.CurrentStepId));
                        authSteps.Add(Context.Definition.Workflow.Steps.Single(s => s.Id == Context.Execution.CurrentStepId));
                        authSteps.AddRange(Context.Definition.Workflow.GetAllChildrenMainLinks(Context.Execution.CurrentStepId));
                        var workflowFormsActingAsStep = Context.Definition.Workflow.Steps
                            .Select(s => formsActingAsStep.FirstOrDefault(st => st.CorrelationId == s.FormRecordCorrelationId))
                            .Where(s => s != null && authSteps.Any(a => a.FormRecordCorrelationId == s.CorrelationId))
                            .Select(s => s.Name);
                        var currentFormRecord = Context.GetCurrentFormRecord();
                        var isActive = true;
                        if (IsNavigationDisplayed)
                        {
                            <ul class="@StepperListClass">
                                @for (var i = 1; i <= workflowFormsActingAsStep.Count(); i++)
                                {
                                    var stepName = workflowFormsActingAsStep.ElementAt(i-1);
                                    <li class="@StepperListItemClass(i == workflowFormsActingAsStep.Count())">
                                        <span class="@StepperListItemContainerClass">
                                            <span class="@StepperListItemNumberClass(isActive)">@i</span>
                                            <span class="@StepperListItemTextClass(isActive)">@stepName</span>
                                        </span>
                                    </li>
                                    if (isActive && stepName == currentFormRecord.Name)
                                    {
                                        isActive = false;
                                    }
                                }
                            </ul>
                        }
                    }
                }

                @if (Context.Execution != null)
                {
                    if (Context.Execution.ErrorMessages != null && Context.Execution.ErrorMessages.Any())
                    {
                        <RadzenAlert AlertStyle="AlertStyle.Danger" Variant="Variant.Flat" Shade="Shade.Lighter">
                            <ul>
                                @foreach (var errorMessage in Context.Execution.ErrorMessages)
                                {
                                    <li>
                                        @TranslateErrorMessage(errorMessage)
                                    </li>

                                }
                            </ul>
                        </RadzenAlert>
                    }

                    if (Context.Execution.SuccessMessages != null && Context.Execution.SuccessMessages.Any())
                    {
                        <RadzenAlert AlertStyle="AlertStyle.Success" Variant="Variant.Flat" Shade="Shade.Lighter">
                            <ul>
                                @foreach (var successMessage in Context.Execution.SuccessMessages)
                                {
                                    <li>
                                        @TranslateSuccessMessage(successMessage)
                                    </li>
                                }
                            </ul>
                        </RadzenAlert>
                    }
                }

                @if (Form?.Elements != null)
                {
                    <RadzenStack class="">
                        @CustomRender
                    </RadzenStack>
                }
            </div>
        </div>
    </div>
</div>

@code {
    private RenderFragment? CustomRender { get; set; }
    [Inject] public IRuleEngine RuleEngine { get; set; }
    [Inject] public IJSRuntime jsRuntime { get; set; }
    [Parameter] public bool IsEditModeEnabled { get; set; }
    [Parameter] public bool IsNavigationDisplayed { get; set; }
    [Parameter] public WorkflowContext Context { get; set; }
    [Parameter] public TemplateWindowDisplayTypes DisplayType { get; set; } = TemplateWindowDisplayTypes.MODAL;
    private FormRecord Form { get; set; } = null;

    string StepperListClass
    {
        get
        {
            return htmlClassResolver.Resolve(Form, FormElementNames.StepperList, Context);
        }
    }

    string StepperListItemClass(bool isEnd)
    {
        var result = htmlClassResolver.Resolve(Form, FormElementNames.StepperListItem, Context);
        if(!isEnd)
        {
            result += " " + htmlClassResolver.Resolve(Form, FormElementNames.StepperListItemActive, Context);
        }

        return result;
    }

    string StepperListItemContainerClass
    {
        get
        {
            return htmlClassResolver.Resolve(Form, FormElementNames.StepperListItemContainer, Context);
        }
    }

    string StepperListItemNumberClass(bool isActive)
    {
        var result =  htmlClassResolver.Resolve(Form, FormElementNames.StepperListItemNumber, Context);
        if(isActive)
        {
            result += " " + htmlClassResolver.Resolve(Form, FormElementNames.StepperListItemNumberActive, Context);
        }

        return result;
    }

    string StepperListItemTextClass(bool isActive)
    {
        var result = htmlClassResolver.Resolve(Form, FormElementNames.StepperListItemText, Context);
        if(isActive)
        {
            result += " " + htmlClassResolver.Resolve(Form, FormElementNames.StepperListItemTextActive, Context);
        }

        return result;
    }

    string ContainerClass
    {
        get
        {
            return htmlClassResolver.Resolve(FormElementNames.Container, Context, DisplayType);
        }
    }

    string ContentClass
    {
        get
        {
            var result = IsEditModeEnabled ? "editor" : "view";
            var resolvedClass = htmlClassResolver.Resolve(FormElementNames.Content, Context, DisplayType);
            if (!string.IsNullOrWhiteSpace(resolvedClass))
            {
                result += $" {resolvedClass}";
            }

            return result;
        }
    }

    string FormContainerClass
    {
        get
        {
            return htmlClassResolver.Resolve(FormElementNames.FormContainer, Context, DisplayType);
        }
    }

    string FormContentClass
    {
        get
        {
            return htmlClassResolver.Resolve(FormElementNames.FormContent, Context, DisplayType);
        }
    }

    public void Dispose()
    {
        if (Form != null) Form.Elements.CollectionChanged -= HandleChanged;
    }

    public void Set(WorkflowContext context)
    {
        Context = context;
        Init();
        StateHasChanged();
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        if (Context == null) return;
        Init();
    }

    private string TranslateSuccessMessage(string message)
    {
        var currentCulture = Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName;
        var translationKey = TranslationKeyParser.Parse(message);
        var translation = Form.SuccessMessageTranslations.SingleOrDefault(t => t.Code == translationKey.Code && t.Language == currentCulture);
        if(translation == null)
        {
            return message;
        }

        return string.Format(translation.Value, translationKey.Args);
    }

    private string TranslateErrorMessage(string message)
    {
        var currentCulture = Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName;
        var translationKey = TranslationKeyParser.Parse(message);
        var translation = Form.ErrorMessageTranslations.SingleOrDefault(t => t.Code == translationKey.Code && t.Language == currentCulture);
        if (translation == null)
        {
            return message;
        }

        return string.Format(translation.Value, translationKey.Args);
    }

    private void Init()
    {
        Form = Context.GetCurrentFormRecord();
        if (Form == null) return;
        RuleEngine.Apply(Context);
        CustomRender = CreateComponent();
        Form.Elements.CollectionChanged += HandleChanged;
        Context.Execution.CurrentStepIdChanged += HandleCurrentStepIdChanged;
    }

    private RenderFragment CreateComponent() => builder =>
    {
        renderFormsElementsHelper.Render(builder, false, 0, Form.Elements, Context, IsEditModeEnabled);
    };

    private void HandleChanged(object sender, NotifyCollectionChangedEventArgs args)
    {
        CustomRender = CreateComponent();
        StateHasChanged();
    }

    private void HandleCurrentStepIdChanged(object sender, EventArgs args)
    {
        Reset();
        Init();
        StateHasChanged();
    }

    private void Reset()
    {
        if (Form != null) Form.Elements.CollectionChanged -= HandleChanged;
        if (Context != null) Context.Execution.CurrentStepIdChanged -= HandleCurrentStepIdChanged;
    }
}